<template>
  <div class="flowchart-editor">
    <!-- 工具栏 -->
    <div class="toolbar bg-white border-b border-gray-200 p-4 flex items-center space-x-4">
      <h2 class="text-lg font-semibold text-gray-800">Mermaid 编辑器 v3.0</h2>

      <!-- 状态指示器 -->
      <div class="flex items-center space-x-4">
        <div class="flex items-center space-x-1">
          <span class="text-sm text-gray-500">mermaid 映射：</span>
          <div :class="isInitialized ? 'bg-green-400' : 'bg-red-400'" class="w-2 h-2 rounded-full"></div>
          <span class="text-xs" :class="isInitialized ? 'text-green-600' : 'text-red-600'">
            {{ isInitialized ? '已初始化' : '初始化失败' }}
          </span>
        </div>
        <span v-if="initializationError" class="text-xs text-red-500" :title="initializationError">⚠️</span>
        <!-- 拖拽性能提示 -->
        <div v-if="isDragging" class="flex items-center space-x-1 bg-blue-50 px-2 py-1 rounded text-blue-800">
          <span class="text-xs">拖拽优化模式：预览暂停</span>
        </div>
      </div>

      <!-- 模板选择 -->
      <!-- <div class="flex items-center space-x-2">
          <label class="text-sm font-medium text-gray-700">模板:</label>
          <select v-model="selectedTemplate" @change="loadTemplate"
            class="px-3 py-1 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
            <option value="">选择模板</option>
            <option v-for="template in templates" :key="template.id" :value="template.id">
              {{ template.name }}
            </option>
          </select>
        </div> -->

      <!-- 图表类型选择 -->

      <p>
        <span>当前图表类型：</span>
        {{ flowType }}
      </p>
      <p>支持图表类型：</p>
      <el-select v-model="selected_chart_type" style="width: 120px">
        <el-option v-for="type in support_chart_types" :key="type" :value="type" />
      </el-select>
      <!-- 操作工具 -->
      <div class="flex items-center space-x-2">
        <button @click="toggleLeftSidebar"
          class="px-3 py-2 bg-gray-500 text-white rounded hover:bg-gray-600 transition-colors text-sm"
          :title="leftSidebarCollapsed ? '展开节点面板 (Ctrl+B)' : '折叠节点面板 (Ctrl+B)'">
          {{ leftSidebarCollapsed ? '展开节点库' : '折叠节点库' }}
        </button>
        <button @click="layoutGraph"
          class="px-3 py-2 bg-green-500 text-white rounded hover:bg-green-600 transition-colors text-sm">
          自动布局
        </button>
        <button @click="clearAll"
          class="px-3 py-2 bg-red-500 text-white rounded hover:bg-red-600 transition-colors text-sm">
          清空
        </button>
        <button @click="exportMermaid"
          class="px-3 py-2 bg-indigo-500 text-white rounded hover:bg-indigo-600 transition-colors text-sm">
          导出代码
        </button>
        <button @click="importMermaid"
          class="px-3 py-2 bg-teal-500 text-white rounded hover:bg-teal-600 transition-colors text-sm">
          导入代码
        </button>
      </div>
    </div>

    <!-- 主编辑区域 -->
    <div class="editor-container flex h-screen">
      <!-- 左侧节点面板 -->
      <div :class="[
        'left-sidebar bg-white border-r border-gray-200 transition-all duration-300 ease-in-out',
        leftSidebarCollapsed ? 'w-12' : 'w-80'
      ]">
        <!-- 折叠/展开按钮 -->
        <div class="flex items-center justify-between p-3 border-b border-gray-200">
          <h3 v-if="!leftSidebarCollapsed" class="text-sm font-medium text-gray-700">节点库</h3>
          <button @click="toggleLeftSidebar" class="p-1 rounded hover:bg-gray-100 transition-colors"
            :title="leftSidebarCollapsed ? '展开节点面板' : '折叠节点面板'">
            <svg v-if="leftSidebarCollapsed" class="w-4 h-4 text-gray-600" fill="none" stroke="currentColor"
              viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
            </svg>
            <svg v-else class="w-4 h-4 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
            </svg>
          </button>
        </div>

        <!-- 节点内容 -->
        <div v-if="!leftSidebarCollapsed" class="p-4">
          <div class="text-xs text-gray-500 mb-4 text-center">拖拽节点到画布</div>
          <el-scrollbar height="calc(100vh - 200px)">
            <Sidebar />
          </el-scrollbar>
        </div>

        <!-- 折叠状态下的节点快捷图标 -->
        <div v-else class="py-2">
          <div class="flex flex-col items-center space-y-2">
            <div v-for="nodeType in quickNodeTypes" :key="nodeType.type" :draggable="true"
              @dragstart="onQuickDragStart($event, nodeType.type)"
              class="quick-node w-8 h-8 border border-gray-300 rounded cursor-grab hover:border-blue-400 hover:bg-blue-50 transition-colors flex items-center justify-center text-xs font-bold text-gray-600"
              :title="nodeType.name">
              {{ nodeType.icon }}
            </div>
          </div>
        </div>
      </div>

      <!-- Vue Flow 画布 -->
      <div class="canvas-area flex-1 relative" @drop="onDropListener">
        <VueFlow :nodes="flowNodes" :edges="flowEdges" v-bind="vueFlowOptions" @node-click="onNodeClick"
          @edge-click="onEdgeClick" @node-context-menu="onNodeContextMenu" @pane-click="onPaneClick"
          @connect="onConnect" @dragover="onDragOver" @dragleave="onDragLeave" :key="flowKey"
          class="vue-flow-container">
          <Background :variant="BackgroundVariant.Dots" :gap="20" :size="1" color="#e5e7eb" />
          <Controls />
          <MiniMap />

          <!-- SVG 定义：箭头标记 -->
          <svg>
            <defs>
              <marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto"
                markerUnits="strokeWidth">
                <path d="M0,0 L0,6 L9,3 z" fill="#6b7280" />
              </marker>
              <marker id="selected-arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto"
                markerUnits="strokeWidth">
                <path d="M0,0 L0,6 L9,3 z" fill="#3b82f6" />
              </marker>
            </defs>
          </svg>

          <!-- 自定义节点模板 -->
          <template #node-rect="{ data, id }">
            <RectNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </RectNode>
          </template>

          <template #node-diamond="{ data, id }">
            <DiamondNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </DiamondNode>
          </template>

          <template #node-asymmetric="{ data, id }">
            <AsymmetricNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </AsymmetricNode>
          </template>

          <template #node-circle="{ data, id }">
            <CircleNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </CircleNode>
          </template>

          <template #node-round="{ data, id }">
            <RoundNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </RoundNode>
          </template>

          <template #node-stadium="{ data, id }">
            <StadiumNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </StadiumNode>
          </template>

          <template #node-subroutine="{ data, id }">
            <SubroutineNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </SubroutineNode>
          </template>

          <template #node-cylindrical="{ data, id }">
            <CylindricalNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </CylindricalNode>
          </template>

          <template #node-hexagon="{ data, id }">
            <HexagonNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </HexagonNode>
          </template>

          <template #node-parallelogram="{ data, id }">
            <ParallelogramNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </ParallelogramNode>
          </template>

          <template #node-trapezoid="{ data, id }">
            <TrapezoidNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </TrapezoidNode>
          </template>

          <template #node-doubleCircle="{ data, id }">
            <DoubleCircleNode :id="id" :data="data">
              <template #top>
                <Handle type="target" :position="Position.Top" />
              </template>
              <template #bottom>
                <Handle type="source" :position="Position.Bottom" />
              </template>
            </DoubleCircleNode>
          </template>

          <!-- 自定义边类型 -->
          <template #edge-default="edgeProps">
            <DefaultEdge v-bind="edgeProps" />
          </template>

          <template #edge-line="edgeProps">
            <LineEdge v-bind="edgeProps" />
          </template>
          <template #edge-line_label="edgeProps">
            <LineEdge v-bind="edgeProps" />
          </template>

          <template #edge-arrow="edgeProps">
            <ArrowEdge v-bind="edgeProps" />
          </template>
          <template #edge-arrow_label="edgeProps">
            <ArrowEdge v-bind="edgeProps" />
          </template>

          <template #edge-dashed="edgeProps">
            <DashedEdge v-bind="edgeProps" />
          </template>
          <template #edge-dashed_label="edgeProps">
            <DashedEdge v-bind="edgeProps" />
          </template>

          <template #edge-dashed_arrow="edgeProps">
            <DashedArrowEdge v-bind="edgeProps" />
          </template>
          <template #edge-dashed_arrow_label="edgeProps">
            <DashedArrowEdge v-bind="edgeProps" />
          </template>

          <template #edge-thick="edgeProps">
            <ThickEdge v-bind="edgeProps" />
          </template>
          <template #edge-thick_label="edgeProps">
            <ThickEdge v-bind="edgeProps" />
          </template>

          <template #edge-thick_arrow="edgeProps">
            <ThickArrowEdge v-bind="edgeProps" />
          </template>
          <template #edge-thick_arrow_label="edgeProps">
            <ThickArrowEdge v-bind="edgeProps" />
          </template>

        </VueFlow>

        <!-- 右键菜单 -->
        <div v-if="contextMenu.show" :style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }"
          class="absolute bg-white border border-gray-200 rounded-lg shadow-lg py-2 z-50">
          <button @click="editNode" class="block w-full px-4 py-2 text-left hover:bg-gray-100 text-sm">
            编辑节点
          </button>
          <button @click="duplicateNode" class="block w-full px-4 py-2 text-left hover:bg-gray-100 text-sm">
            复制节点
          </button>
          <button @click="deleteNode" class="block w-full px-4 py-2 text-left hover:bg-gray-100 text-red-600 text-sm">
            删除节点
          </button>
        </div>
      </div>

      <!-- 右侧面板 -->
      <div class="sidebar w-80 bg-white border-l border-gray-200 px-4 pb-4 overflow-y-auto">
        <!-- 移除节点标签页，只保留 Mermaid 代码 -->
        <div class="py-4">
          <h3 class="text-lg font-semibold mb-4">Mermaid 代码</h3>

          <!-- 连接属性编辑 - 改进版本 -->
          <div v-if="selectedEdge" class="mb-6">
            <h4 class="text-md font-semibold mb-3">连接属性</h4>
            <div class="space-y-3">
              <div>
                <label class="block text-sm font-medium text-gray-700 mb-1">连接标签</label>
                <input v-model="selectedEdge.label" type="text"
                  class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                  @input="onEdgeLabelChange" placeholder="输入连接标签（可选）" />
              </div>
              <p>{{ selectedEdge.baseType }}</p>
              <div>
                <label class="block text-sm font-medium text-gray-700 mb-1">连接样式</label>
                <select v-model="selectedEdge.baseType" @change="onEdgeStyleChange"
                  class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
                  <option value="line">直线</option>
                  <option value="arrow">箭头</option>
                  <option value="dashed">虚线</option>
                  <option value="dashed_arrow">虚线箭头</option>
                  <option value="thick">粗线</option>
                  <option value="thick_arrow">粗线箭头</option>
                </select>
              </div>
            </div>
          </div>

          <!-- 兼容性检查 -->
          <div v-if="compatibilityIssues.length > 0" class="mb-6">
            <h4 class="text-md font-semibold mb-3 text-orange-600">兼容性提示</h4>
            <div class="space-y-2">
              <div v-for="issue in compatibilityIssues" :key="issue.id"
                class="p-3 bg-orange-50 border border-orange-200 rounded-md">
                <div class="text-sm font-medium text-orange-800">{{ issue.type }}</div>
                <div class="text-xs text-orange-600 mt-1">{{ issue.message }}</div>
                <div class="text-xs text-orange-500 mt-1">建议: {{ issue.suggestion }}</div>
              </div>
            </div>
          </div>

          <!-- Mermaid 代码预览 -->
          <div class="mb-6">
            <h4 class="text-md font-semibold mb-3">代码预览</h4>
            <textarea v-model="mermaidCode"
              class="w-full h-48 p-3 border border-gray-300 rounded-md bg-gray-50 font-mono text-sm resize-none"
              placeholder="Mermaid代码将在这里显示..." readonly></textarea>
            <div class="flex space-x-2 mt-2">
              <button @click="copyMermaidCode"
                class="flex-1 px-3 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors text-sm">
                复制代码
              </button>
              <button @click="validateMermaidCode"
                class="flex-1 px-3 py-2 bg-green-500 text-white rounded hover:bg-green-600 transition-colors text-sm">
                验证代码
              </button>
            </div>
          </div>

          <!-- Mermaid 预览 -->
          <div class="mb-6">
            <h4 class="text-md font-semibold mb-3">图表预览</h4>
            <div ref="mermaidPreview" class="border border-gray-300 rounded-md p-4 bg-white min-h-32"></div>
            <div class="flex space-x-2 mt-2">
              <button @click="openPreviewDialog"
                class="flex-1 px-3 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors text-sm">
                全屏预览
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 编辑对话框 -->
    <div v-if="editDialog.show" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
      <div class="bg-white rounded-lg p-6 w-96">
        <h3 class="text-lg font-semibold mb-4">编辑节点</h3>
        <div class="space-y-4">
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">节点文本</label>
            <input v-model="editDialog.text" type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md"
              @keyup.enter="saveNodeEdit" />
          </div>
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">节点类型</label>
            <select v-model="editDialog.type" class="w-full px-3 py-2 border border-gray-300 rounded-md">
              <option value="rect">矩形</option>
              <option value="round">圆角矩形</option>
              <option value="stadium">体育场形</option>
              <option value="subroutine">子程序</option>
              <option value="cylindrical">圆柱形</option>
              <option value="circle">圆形</option>
              <option value="asymmetric">非对称</option>
              <option value="diamond">菱形</option>
              <option value="hexagon">六边形</option>
              <option value="parallelogram">平行四边形</option>
              <option value="trapezoid">梯形</option>
              <option value="doubleCircle">双圆</option>
            </select>
          </div>
        </div>
        <div class="flex justify-end space-x-3 mt-6">
          <button @click="editDialog.show = false" class="px-4 py-2 text-gray-600 hover:text-gray-800">
            取消
          </button>
          <button @click="saveNodeEdit" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
            保存
          </button>
        </div>
      </div>
    </div>

    <!-- 导入对话框 -->
    <div v-if="importDialog.show" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
      <div class="bg-white rounded-lg p-6 w-[600px]">
        <h3 class="text-lg font-semibold mb-4">导入 Mermaid 代码</h3>
        <div class="space-y-4">
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">Mermaid 代码</label>
            <textarea v-model="importDialog.code"
              class="w-full h-48 p-3 border border-gray-300 rounded-md font-mono text-sm"
              placeholder="粘贴您的 Mermaid 代码..."></textarea>
          </div>
          <div v-if="importDialog.errors.length > 0" class="text-red-600 text-sm">
            <div class="font-medium mb-1">导入错误:</div>
            <ul class="list-disc list-inside space-y-1">
              <li v-for="error in importDialog.errors" :key="error">{{ error }}</li>
            </ul>
          </div>
        </div>
        <div class="flex justify-end space-x-3 mt-6">
          <button @click="importDialog.show = false" class="px-4 py-2 text-gray-600 hover:text-gray-800">
            取消
          </button>
          <button @click="parseImportedCode" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
            导入
          </button>
        </div>
      </div>
    </div>

    <!-- 预览对话框 -->
    <el-dialog v-model="preview_visible" @opened="preview_dialog_opened" title="图标预览弹窗">
      <div ref="dialogMermaidPreview" class="border border-gray-300 rounded-md p-4 bg-white min-h-32"></div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick, onBeforeUnmount } from 'vue'
import { VueFlow, useVueFlow } from '@vue-flow/core'
import { Background, BackgroundVariant } from '@vue-flow/background'
import { Controls } from '@vue-flow/controls'
import { MiniMap } from '@vue-flow/minimap'
import type { Node, Connection } from '@vue-flow/core'
import { Handle, Position } from '@vue-flow/core'
import mermaid from 'mermaid'

import Sidebar from '@/components/MermaidEdit/Sidebar.vue'
import RectNode from '@/components/MermaidEdit/nodes/RectNode.vue'
import DiamondNode from '@/components/MermaidEdit/nodes/DiamondNode.vue'
import AsymmetricNode from '@/components/MermaidEdit/nodes/AsymmetricNode.vue'
import CircleNode from '@/components/MermaidEdit/nodes/CircleNode.vue'
import RoundNode from '@/components/MermaidEdit/nodes/RoundNode.vue'
import StadiumNode from '@/components/MermaidEdit/nodes/StadiumNode.vue'
import SubroutineNode from '@/components/MermaidEdit/nodes/SubroutineNode.vue'
import CylindricalNode from '@/components/MermaidEdit/nodes/CylindricalNode.vue'
import HexagonNode from '@/components/MermaidEdit/nodes/HexagonNode.vue'
import ParallelogramNode from '@/components/MermaidEdit/nodes/ParallelogramNode.vue'
import TrapezoidNode from '@/components/MermaidEdit/nodes/TrapezoidNode.vue'
import DoubleCircleNode from '@/components/MermaidEdit/nodes/DoubleCircleNode.vue'

import DefaultEdge from '@/components/MermaidEdit/edges/DefaultEdge.vue'
import DashedEdge from '@/components/MermaidEdit/edges/DashedEdge.vue'
import DashedArrowEdge from '@/components/MermaidEdit/edges/DashedArrowEdge.vue'
import LineEdge from '@/components/MermaidEdit/edges/LineEdge.vue'
import ArrowEdge from '@/components/MermaidEdit/edges/ArrowEdge.vue'
import ThickEdge from '@/components/MermaidEdit/edges/ThickEdge.vue'
import ThickArrowEdge from '@/components/MermaidEdit/edges/ThickArrowEdge.vue'


import {
  MermaidSyntax,
  type MermaidNode,
  type MermaidConnection,
  type CompatibilityIssue
} from '../assets/mermaid_syntax'
import { useLayout } from '../assets/vueflow/useLayout'
import useDragAndDrop from '../assets/vueflow/useDnD'


const { onDragOver, onDrop, onDragLeave } = useDragAndDrop()

const selected_chart_type = ref('')
const support_chart_types = ref([])

const preview_visible = ref(false)

function openPreviewDialog() {
  preview_visible.value = true
}

function preview_dialog_opened() {
  if (dialogMermaidPreview.value && mermaidPreview.value) {
    dialogMermaidPreview.value.innerHTML = mermaidPreview.value.innerHTML
  }
}

// 左侧边栏状态
const leftSidebarCollapsed = ref(false)

// 快捷节点类型（折叠状态下显示）
const quickNodeTypes = ref([
  { type: 'rect', name: '矩形节点', icon: '□' },
  { type: 'diamond', name: '菱形节点', icon: '◇' },
  { type: 'circle', name: '圆形节点', icon: '○' },
  { type: 'round', name: '圆角矩形节点', icon: '▢' },
  { type: 'stadium', name: '体育场形节点', icon: '◯' },
  { type: 'cylindrical', name: '圆柱形节点', icon: '⬮' }
])

// 切换左侧边栏
const toggleLeftSidebar = () => {
  leftSidebarCollapsed.value = !leftSidebarCollapsed.value
}

// 快捷拖拽开始
const onQuickDragStart = (event: DragEvent, type: string) => {
  if (event.dataTransfer) {
    event.dataTransfer.setData('application/vueflow', type)
    event.dataTransfer.effectAllowed = 'move'
  }
}

// Vue Flow 接口定义
interface FlowNode extends Node {
  data: {
    label: string
    nodeType: string
  }
}

interface FlowEdge {
  id: string
  source: string
  target: string
  type?: string
  label?: string
  baseType?: string  // 基础样式类型
  showLabel?: boolean // 是否显示标签
  edgeType?: string
}


// 响应式数据
const mermaidPreview = ref<HTMLElement>()
const dialogMermaidPreview = ref<HTMLElement>()
const selectedNode = ref<FlowNode | null>(null)
const selectedEdge = ref<FlowEdge | null>(null)
const mermaidCode = ref('')
const compatibilityIssues = ref<CompatibilityIssue[]>([])

// Vue Flow 数据
const flowNodes = ref<FlowNode[]>([])
const flowEdges = ref<FlowEdge[]>([])
const flowType = ref('none')
const flowKey = ref(0) // 用于强制重新渲染 Vue Flow

// 语法映射工具
let syntaxUtils: any = null
const isInitialized = ref(false)
const initializationError = ref('')

// 右键菜单
const contextMenu = reactive({
  show: false,
  x: 0,
  y: 0,
  nodeId: null as string | null
})

// 编辑对话框
const editDialog = reactive({
  show: false,
  node: null as FlowNode | null,
  text: '',
  type: 'default'
})

// 导入对话框
const importDialog = reactive({
  show: false,
  code: '',
  errors: [] as string[]
})

let nodeIdCounter = 1

// Vue Flow 实例
const { fitView } = useVueFlow()

// 性能优化配置
const vueFlowOptions = {
  defaultViewport: { zoom: 1 },
  minZoom: 0.2,
  maxZoom: 4,
  connectionLineStyle: { stroke: '#9ca3af', strokeWidth: 2, strokeDasharray: '5,5' },

  // 性能相关配置
  elevateNodesOnSelect: true,     // 选中节点时提升节点层级
  autoPanOnNodeDrag: true,        // 节点拖至边缘时自动平移
  applyDefault: true,             // 使用默认设置
  // selectionKeyCode: 'Control',    // 多选键
  // multiSelectionKeyCode: 'Shift', // 多选组合键
  snapToGrid: false,              // 不启用网格吸附(启用可能影响性能)
  renderModes: true,              // 启用渲染模式优化

  // 拖拽优化配置
  nodesDraggable: true,           // 允许节点拖拽
  nodesConnectable: true,         // 允许节点连接
  elementsSelectable: true,       // 允许元素选择
  panOnDrag: true,                // 允许拖拽画布
  panOnScroll: true,              // 允许滚动画布
  useVirtualization: true,        // 使用虚拟化优化大量节点
}

const { layout } = useLayout()

// 自动布局
function layoutGraph() {
  // LR, TB, RL, BT
  flowNodes.value = layout(flowNodes.value, flowEdges.value, 'TB')
  nextTick(() => {
    fitView()
  })
}

// 初始化
onMounted(async () => {
  // 初始化 Mermaid
  mermaid.initialize({
    startOnLoad: true,
    theme: 'default',
    flowchart: {
      useMaxWidth: true,
      htmlLabels: true
    }
  })

  // 初始化语法映射系统
  console.log('开始初始化语法映射系统...')
  try {
    syntaxUtils = new MermaidSyntax()
    await syntaxUtils.init_mapping()
    if (syntaxUtils.chart_type != '') {
      // templates.value = syntaxUtils.getTemplates('flowchart')
      isInitialized.value = true
      support_chart_types.value = syntaxUtils.support_chart_types
      selected_chart_type.value = syntaxUtils.support_chart_types[0]
      flowType.value = syntaxUtils.support_chart_types[0]
      console.log('语法映射系统初始化成功')
    } else {
      throw new Error('MermaidSyntax 返回了 null 或 undefined')
    }
  } catch (error: any) {
    const errorMessage = `语法映射系统初始化失败: ${error?.message || '未知错误'}`
    console.error(errorMessage, error)
    initializationError.value = errorMessage
    isInitialized.value = false
  }

  // 添加全局事件监听器
  document.addEventListener('click', hideContextMenu)
  document.addEventListener('keydown', onKeyDown)
})

// 组件卸载时清理资源
onBeforeUnmount(() => {
  console.log('清理资源...')

  // 清除所有计时器
  if (updateTimeout) clearTimeout(updateTimeout)
  if (renderTimeout) clearTimeout(renderTimeout)

  // 移除事件监听器
  document.removeEventListener('click', hideContextMenu)
  document.removeEventListener('keydown', onKeyDown)

  // 清空数据引用
  flowNodes.value = []
  flowEdges.value = []
  selectedNode.value = null
  selectedEdge.value = null

  // 释放工具类实例
  syntaxUtils = null
})

// 键盘事件处理
const onKeyDown = (event: KeyboardEvent) => {
  if (event.key === 'Delete') {
    if (selectedNode.value) {
      deleteSelectedNode()
    } else if (selectedEdge.value) {
      deleteSelectedEdge()
    }
  }
  if (event.key === 'Escape') {
    selectedNode.value = null
    selectedEdge.value = null
  }
  // 快捷键切换左侧边栏：Ctrl/Cmd + B
  if ((event.ctrlKey || event.metaKey) && event.key === 'b') {
    event.preventDefault()
    toggleLeftSidebar()
  }
}

const duplicateNode = () => {
  if (!contextMenu.nodeId) return

  const originalNode = flowNodes.value.find(n => n.id === contextMenu.nodeId)
  if (!originalNode) return

  const newNode: FlowNode = {
    ...originalNode,
    id: `node_${nodeIdCounter++}`,
    position: {
      x: originalNode.position.x + 50,
      y: originalNode.position.y + 50
    },
    data: {
      ...originalNode.data,
      label: originalNode.data.label + ' (副本)'
    }
  }

  flowNodes.value.push(newNode)
  updateMermaidCode()
  hideContextMenu()
}

const deleteNode = () => {
  if (!contextMenu.nodeId) return

  // 删除节点
  flowNodes.value = flowNodes.value.filter(n => n.id !== contextMenu.nodeId)

  // 删除相关边
  flowEdges.value = flowEdges.value.filter(
    e => e.source !== contextMenu.nodeId && e.target !== contextMenu.nodeId
  )

  if (selectedNode.value?.id === contextMenu.nodeId) {
    selectedNode.value = null
  }

  updateMermaidCode()
  hideContextMenu()
}

const deleteSelectedNode = () => {
  if (!selectedNode.value) return

  // 删除节点
  flowNodes.value = flowNodes.value.filter(n => n.id !== selectedNode.value!.id)

  // 删除相关边
  flowEdges.value = flowEdges.value.filter(
    e => e.source !== selectedNode.value!.id && e.target !== selectedNode.value!.id
  )

  selectedNode.value = null
  updateMermaidCode()
}

const deleteSelectedEdge = () => {
  if (!selectedEdge.value) return

  flowEdges.value = flowEdges.value.filter(e => e.id !== selectedEdge.value!.id)
  selectedEdge.value = null
  updateMermaidCode()
}

const clearAll = () => {
  flowNodes.value = []
  flowEdges.value = []
  selectedNode.value = null
  selectedEdge.value = null
  compatibilityIssues.value = []
  mermaidCode.value = ''
  if (mermaidPreview.value) {
    mermaidPreview.value.innerHTML = '<p class="text-gray-500">暂无内容</p>'
  }
}

// Vue Flow 事件处理
function onDropListener(event: DragEvent) {
  const node = onDrop(event)
  flowNodes.value.push(node)
  updateMermaidCode()
}

const onNodeClick = (event: any) => {
  selectedNode.value = event.node
  selectedEdge.value = null
}

// const onEdgeClick = (event: any) => {
//   selectedEdge.value = event.edge
//   // 确保边有 edgeType 属性，如果没有则设置默认值
//   if (selectedEdge.value && !selectedEdge.value.edgeType) {
//     selectedEdge.value.edgeType = selectedEdge.value.type || 'default'
//   }
//   selectedNode.value = null
// }

const onPaneClick = () => {
  selectedNode.value = null
  selectedEdge.value = null
}

const onNodeContextMenu = (event: any) => {
  event.event.preventDefault()
  contextMenu.show = true
  contextMenu.x = event.event.layerX
  contextMenu.y = event.event.layerY + 20
  contextMenu.nodeId = event.node.id
}

// const onConnect = (connection: Connection) => {
//   const newEdge: FlowEdge = {
//     id: `edge_${Date.now()}_${Math.random()}`,
//     source: connection.source!,
//     target: connection.target!,
//     type: 'default',
//     edgeType: 'default'
//   }

//   flowEdges.value.push(newEdge)
//   updateMermaidCode()
// }

// 添加节流变量
let updateTimeout: number | null = null
let isDragging = false

const hideContextMenu = () => {
  contextMenu.show = false
  contextMenu.nodeId = null
}

// 编辑操作
const editNode = () => {
  if (!contextMenu.nodeId) return
  const node = flowNodes.value.find(n => n.id === contextMenu.nodeId)
  if (!node) return

  editDialog.show = true
  editDialog.node = node
  editDialog.text = node.data.label
  editDialog.type = node.type || 'default'
  hideContextMenu()
}

const saveNodeEdit = () => {
  if (editDialog.node) {
    editDialog.node.data.label = editDialog.text
    editDialog.node.type = editDialog.type
    editDialog.node.data.nodeType = editDialog.type
    updateMermaidCode()
  }
  editDialog.show = false
  editDialog.node = null
}

// 修改边样式处理逻辑
const onEdgeStyleChange = async () => {
  if (selectedEdge.value) {
    // 根据基础类型和是否显示标签决定最终类型
    const hasLabel = selectedEdge.value.label && selectedEdge.value.label.trim() !== ''
    const shouldShowLabel = selectedEdge.value.showLabel && hasLabel

    let finalType = selectedEdge.value.baseType || 'line'
    if (shouldShowLabel) {
      finalType = finalType + '_label'
    }
    const edgeIndex = flowEdges.value.findIndex(edge => edge.id === selectedEdge.value!.id)
    if (edgeIndex !== -1) {
      const newEdges = [...flowEdges.value]
      newEdges[edgeIndex] = {
        ...newEdges[edgeIndex],
        type: finalType,
        edgeType: finalType,
        baseType: selectedEdge.value.baseType,
        showLabel: selectedEdge.value.showLabel
      }

      flowEdges.value = newEdges
      selectedEdge.value = newEdges[edgeIndex]
      flowKey.value++
    }
  }
  updateMermaidCode()
}

// 修改标签变化处理
const onEdgeLabelChange = () => {
  if (selectedEdge.value) {
    const edgeIndex = flowEdges.value.findIndex(edge => edge.id === selectedEdge.value!.id)
    if (edgeIndex !== -1) {
      flowEdges.value[edgeIndex].label = selectedEdge.value.label

      // 如果有标签内容，自动决定是否显示
      const hasLabel = selectedEdge.value.label && selectedEdge.value.label.trim() !== ''
      if (hasLabel && selectedEdge.value.showLabel !== false) {
        selectedEdge.value.showLabel = true
      }

      // 延迟更新样式
      setTimeout(() => {
        onEdgeStyleChange()
      }, 300)
    }
  }
}

// 修改连接创建逻辑
const onConnect = (connection: Connection) => {
  const newEdge: FlowEdge = {
    id: `edge_${Date.now()}_${Math.random()}`,
    source: connection.source!,
    target: connection.target!,
    type: 'line',
    baseType: 'line',
    showLabel: true,
    edgeType: 'line'
  }

  flowEdges.value.push(newEdge)
  updateMermaidCode()
}

// 修改边点击逻辑
const onEdgeClick = (event: any) => {
  selectedEdge.value = event.edge
  // 确保边有必要的属性
  if (selectedEdge.value && !selectedEdge.value.baseType) {
    // 从现有的edgeType推断baseType
    const edgeType = selectedEdge.value.edgeType || selectedEdge.value.type || 'line'
    selectedEdge.value.baseType = edgeType.replace('_label', '')
    selectedEdge.value.showLabel = edgeType.includes('_label')
  }
  selectedNode.value = null
}

// Mermaid 代码操作
const updateMermaidCode = async () => {
  // 如果正在拖拽中，不更新代码
  if (isDragging) {
    return
  }

  if (!syntaxUtils || flowNodes.value.length === 0) {
    mermaidCode.value = ''
    compatibilityIssues.value = []
    if (mermaidPreview.value) {
      mermaidPreview.value.innerHTML = '<p class="text-gray-500">暂无内容</p>'
    }
    return
  }

  try {
    // 转换为Mermaid节点格式
    const mermaidNodes: MermaidNode[] = flowNodes.value.map(node => ({
      id: node.id,
      type: node.data.nodeType,
      text: node.data.label
    }))

    // 转换为Mermaid连接格式
    const mermaidConnections: MermaidConnection[] = flowEdges.value.map(edge => ({
      from: edge.source,
      to: edge.target,
      type: edge.edgeType || 'arrow',
      label: edge.label
    }))

    // 生成Mermaid代码
    // const code = syntaxUtils.generateMermaidCode.generate(mermaidNodes, mermaidConnections)
    const visualChart = {
      type: flowType.value,
      direction: 'TD',
      nodes: mermaidNodes,
      connections: mermaidConnections,
      directives: []
    }

    const code = syntaxUtils.MermaidCodeGenerator().generate(visualChart)

    mermaidCode.value = code

    // 检查兼容性
    // const issues = syntaxUtils.analyzeCompatibility(mermaidNodes, mermaidConnections)
    // compatibilityIssues.value = issues

    // 渲染预览
    await renderPreview(code)
  } catch (error) {
    console.error('Failed to update Mermaid code:', error)
    if (mermaidPreview.value) {
      mermaidPreview.value.innerHTML = '<p class="text-red-500">代码生成失败</p>'
    }
  }
}

// 渲染预览节流控制
let renderTimeout: number | null = null

const renderPreview = async (code: string) => {
  // 如果正在拖拽，则不进行渲染
  if (isDragging) {
    return
  }

  // 使用节流控制，避免频繁渲染
  if (renderTimeout) {
    clearTimeout(renderTimeout)
  }

  renderTimeout = window.setTimeout(async () => {
    await nextTick()
    if (mermaidPreview.value) {
      try {
        mermaidPreview.value.innerHTML = '<p class="text-gray-500">正在生成预览...</p>'
        const { svg } = await mermaid.render('mermaid-preview', code)
        mermaidPreview.value.innerHTML = svg
      } catch (error) {
        console.error('Mermaid render error:', error)
        mermaidPreview.value.innerHTML = '<p class="text-red-500">预览渲染失败</p>'
      }
    }
    renderTimeout = null
  }, 400) // 设置一个合理的节流间隔
}

const exportMermaid = () => {
  updateMermaidCode()
}

const importMermaid = () => {
  importDialog.show = true
  importDialog.code = ''
  importDialog.errors = []
}

const parseImportedCode = async () => {
  if (!importDialog.code || !importDialog.code.trim()) {
    importDialog.errors = ['请输入Mermaid代码']
    return
  }

  if (!isInitialized.value) {
    if (initializationError.value) {
      importDialog.errors = [`初始化错误: ${initializationError.value}`, '将使用基础解析功能']
    } else {
      importDialog.errors = ['语法解析工具未初始化，将使用基础解析功能']
    }
  }

  try {
    const parsed = syntaxUtils.MermaidSyntaxParser().parse(importDialog.code)

    // alert(`图表类型: ${parsed.ast.chartType}`)

    if (!parsed.ast.nodes || parsed.ast.nodes.length === 0) {
      importDialog.errors = ['未能从代码中识别到有效的节点定义，请检查代码格式']
      return
    }

    clearAll()

    flowType.value = parsed.ast.chartType

    // 添加解析的节点
    const nodes: FlowNode[] = parsed.ast.nodes.map((node: MermaidNode, index: number) => ({
      id: node.id,
      type: node.type,
      position: {
        x: 150 + (index % 4) * 200,
        y: 150 + Math.floor(index / 4) * 150
      },
      data: {
        label: node.text,
        nodeType: node.type
      }
    }))

    // 添加解析的边
    const edges: FlowEdge[] = parsed.ast.connections.map((conn: MermaidConnection) => ({
      id: `edge_${Date.now()}_${Math.random()}`,
      source: conn.from,
      target: conn.to,
      label: conn.label,
      type: conn.type,
      showLabel: true,
      edgeType: conn.type,
      baseType: conn.type,
    }))

    flowNodes.value = nodes
    flowEdges.value = edges

    updateMermaidCode()

    nextTick(() => {
      layoutGraph()
    })

    importDialog.show = false
    importDialog.errors = []
  } catch (error: any) {
    importDialog.errors = [`解析失败: ${error?.message || '未知错误'}`]
  }
}

const copyMermaidCode = async () => {
  try {
    await navigator.clipboard.writeText(mermaidCode.value)
  } catch (error) {
    console.error('复制失败:', error)
  }
}

const validateMermaidCode = async () => {
  if (!mermaidCode.value.trim()) {
    alert('没有可验证的代码')
    return
  }

  try {
    await mermaid.parse(mermaidCode.value)
    alert('代码语法正确！')
  } catch (error: any) {
    alert(`代码语法错误: ${error?.message || '未知错误'}`)
  }
}

// 组件卸载时清理资源
onBeforeUnmount(() => {

  // 清除所有计时器
  if (updateTimeout) clearTimeout(updateTimeout)
  if (renderTimeout) clearTimeout(renderTimeout)

  // 移除事件监听器
  document.removeEventListener('click', hideContextMenu)
  document.removeEventListener('keydown', onKeyDown)

  // 清空数据引用
  flowNodes.value = []
  flowEdges.value = []
  selectedNode.value = null
  selectedEdge.value = null

  // 释放工具类实例
  syntaxUtils = null
})
</script>

<style scoped>
.flowchart-editor {
  height: 100vh;
  overflow: hidden;
}

.editor-container {
  height: calc(100vh - 80px);
}

.canvas-area {
  position: relative;
  overflow: hidden;
}

.toolbar {
  height: 80px;
}

.sidebar {
  max-height: calc(100vh - 80px);
}

.left-sidebar {
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  position: relative;
  z-index: 10;
}

.vue-flow-container {
  background: #f9fafb;
}

/* 左侧边栏动画效果 */
.left-sidebar {
  transition: width 0.3s ease-in-out;
}

/* 快捷节点图标样式 */
.left-sidebar .quick-node {
  transition: all 0.2s ease-in-out;
}

.left-sidebar .quick-node:hover {
  transform: scale(1.1);
  border-color: #3b82f6;
  background-color: #eff6ff;
}

.vue-flow-container {
  background: #f9fafb;
}

/* Vue Flow 样式覆盖 */
:deep(.vue-flow__node-default.selected) {
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

:deep(.vue-flow__node.selected>div, .vue-flow__node-default.selected) {
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

:deep(.vue-flow__edge) {
  stroke-width: 1;
}

/* 虚线边样式 */
:deep(.vue-flow__edge[data-type="dashed"]) {
  stroke-dasharray: 5, 5;
  stroke-width: 2;
}

/* 点线边样式 */
:deep(.vue-flow__edge[data-type="dotted"]) {
  stroke-dasharray: 2, 3;
  stroke-width: 2;
  stroke-linecap: round;
}

:deep(.vue-flow__edge.selected .vue-flow__edge-text) {
  fill: #3b82f6;
}

:deep(.vue-flow__edge-text) {
  font-size: 12px;
  fill: #000;
  background: white;
  padding: 2px 4px;
  border-radius: 4px;
}

:deep(.vue-flow__handle) {
  width: 8px;
  height: 8px;
  background: #3b82f6;
  border: 2px solid white;
  border-radius: 50%;
}

:deep(.vue-flow__handle:hover) {
  background: #2563eb;
}

:deep(.vue-flow__controls) {
  bottom: 20px;
  left: 20px;
}

:deep(.vue-flow__minimap) {
  bottom: 20px;
  right: 20px;
}
</style>